package com.bskj.bms.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bskj.bms.bean.req.UserListReqVo;
import com.bskj.bms.bean.vo.AllInfoUserVo;
import com.bskj.bms.bean.vo.MenuTreeVo;
import com.bskj.bms.service.IBmsUserService;
import com.bskj.common.bean.model.BmsResource;
import com.bskj.common.bean.model.BmsRole;
import com.bskj.common.bean.model.BmsRoleResource;
import com.bskj.common.bean.model.BmsUser;
import com.bskj.common.bean.model.BmsUserRole;
import com.bskj.common.bean.model.ParkingLotCustomer;
import com.bskj.common.bean.model.ParkingShop;
import com.bskj.common.bean.model.PropertyCompanies;
import com.bskj.common.dao.BmsResourceDao;
import com.bskj.common.dao.BmsRoleDao;
import com.bskj.common.dao.BmsRoleResourceDao;
import com.bskj.common.dao.BmsUserDao;
import com.bskj.common.dao.BmsUserRoleDao;
import com.bskj.common.dao.ParkingLotCustomerDao;
import com.bskj.common.dao.ParkingShopDao;
import com.bskj.common.dao.PropertyCompaniesDao;
import com.bskj.common.dao.core.BaseDao;
import com.bskj.common.dao.core.FindRequestEntity;
import com.bskj.common.dao.core.OrderEnum;
import com.bskj.common.dao.core.Page;
import com.bskj.common.dao.core.WhereEnum;
import com.bskj.common.enums.BmsUserTypeEnum;
import com.bskj.common.enums.UserStatusEnum;
import com.bskj.common.service.impl.BaseServiceImpl;
import com.bskj.common.utils.DateTimeUtil;
import com.bskj.common.utils.EncryptUtil;
import com.bskj.common.utils.StringUtils;

@Service
public class BmsUserServiceImpl extends BaseServiceImpl<BmsUser> implements IBmsUserService {
	@Autowired
	private BmsUserDao bmsUserDao;

	@Autowired
	private BmsUserRoleDao bmsUserRoleDao;

	@Autowired
	private BmsRoleDao bmsRoleDao;

	@Autowired
	private BmsRoleResourceDao bmsRoleResourceDao;

	@Autowired
	private BmsResourceDao bmsResourceDao;

	@Autowired
	private ParkingLotCustomerDao parkingLotCustomerDao;

	@Autowired
	private ParkingShopDao parkingShopDao;

	@Autowired
	private PropertyCompaniesDao propertyCompaniesDao;

	@Override
	public BaseDao<BmsUser> getBaseDao() {
		return bmsUserDao;
	}

	@Override
	public BmsUser findUser(String username, String password) throws Exception {
		FindRequestEntity findUserReq = new FindRequestEntity();
		findUserReq.addWhere("ent_no", WhereEnum.EQ, username);
		findUserReq.addWhere("status", WhereEnum.NE, UserStatusEnum.delete.getKey());
		findUserReq.addWhere("password", WhereEnum.EQ, EncryptUtil.getMD5(password));

		List<BmsUser> bmsUserList = find(findUserReq);
		if (bmsUserList != null && bmsUserList.size() > 0) {
			return bmsUserList.get(0);
		}
		return null;
	}

	public Map<String, Object> loadBmsUserRoleResource(BmsUser bmsUser) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		/**
		 * 处理三件事 1、获取一个角色名，用于显示 2、获取菜单树，用于展示 3、获取资源列表，用于权限控制
		 */

		if (bmsUser == null || bmsUser.getId() == null) {
			return resultMap;
		}
		resultMap.put("user", bmsUser);

		// 找出用户所有资源
		FindRequestEntity findUserRoleReq = new FindRequestEntity();
		findUserRoleReq.addWhere("user_id", WhereEnum.EQ, bmsUser.getId());
		List<BmsUserRole> useRoleList = bmsUserRoleDao.find(findUserRoleReq);
		Set<BmsResource> resourceSet = new HashSet<>();
		if (useRoleList != null && useRoleList.size() > 0) {
			// 用户角色名 ，只展示第一个
			BmsRole role = bmsRoleDao.get(useRoleList.get(0).getRoleId());
			if (role != null) {
				// 1、获取一个角色名，用于显示
				resultMap.put("roleName", role.getName());
			}

			for (BmsUserRole userRole : useRoleList) {
				FindRequestEntity findResourceReq = new FindRequestEntity();
				findResourceReq.addWhere("role_id", WhereEnum.EQ, userRole.getRoleId());

				List<BmsRoleResource> roleResourceList = bmsRoleResourceDao.find(findResourceReq);
				if (roleResourceList != null && roleResourceList.size() > 0) {
					for (BmsRoleResource roleResource : roleResourceList) {
						BmsResource resource = bmsResourceDao.get(roleResource.getResourceId());
						if (resource != null) {
							resourceSet.add(resource);
						}
					}
				}
			}

			if (resourceSet.size() == 0) {
				return resultMap;
			}

			// step 2、获得菜单树
			// 排序
			List<BmsResource> resourceList = new ArrayList<>();
			resourceList.addAll(resourceSet);
			Collections.sort(resourceList);
			List<MenuTreeVo> menuTreeList = new ArrayList<>();
			// 获取顶级菜单
			for (BmsResource bmsResource : resourceList) {
				if (bmsResource.getLevel() == 1) {
					MenuTreeVo topMenuTree = new MenuTreeVo();
					topMenuTree.setName(bmsResource.getName());
					topMenuTree.setUrl(bmsResource.getUrl());
					List<MenuTreeVo> childTreeList = new ArrayList<>();
					// 获取子菜单（只往下取一级，因为菜单只有2层）
					for (BmsResource childResource : resourceList) {
						if (bmsResource.getId().equals(childResource.getParentId())) {
							MenuTreeVo childTree = new MenuTreeVo();
							childTree.setName(childResource.getName());
							childTree.setUrl(childResource.getUrl());
							childTreeList.add(childTree);
						}
					}
					topMenuTree.setChildTree(childTreeList);
					menuTreeList.add(topMenuTree);
				}
			}
			resultMap.put("menuTree", menuTreeList);

			// step 3、获取资源列表
			Set<String> resourceUrlList = new HashSet<>();
			for (BmsResource bmsResource : resourceList) {
				if (!StringUtils.isBank(bmsResource.getUrl())) {
					resourceUrlList.add(bmsResource.getUrl());
				}
			}
			resultMap.put("resourceList", resourceUrlList);
		}
		if (bmsUser.getType() == BmsUserTypeEnum.parking_lot_user.getKey()) {
			ParkingLotCustomer parkingLotCustomer = parkingLotCustomerDao.get(bmsUser.getCustId());
			resultMap.put("parkName", parkingLotCustomer.getParkingName());
		} else if (bmsUser.getType() == BmsUserTypeEnum.property_cust.getKey()) {
			PropertyCompanies propertyCompanies = propertyCompaniesDao.get(bmsUser.getPropId());
			resultMap.put("parkName", propertyCompanies.getPropertyName());
		}
		return resultMap;
	}

	@Override
	public Page<AllInfoUserVo> pageUser(UserListReqVo req) throws Exception {
		FindRequestEntity findReq = new FindRequestEntity();
		findReq.addWhere("status", WhereEnum.NE, UserStatusEnum.delete.getKey());
		if (!StringUtils.isBank(req.getEntNo())) {
			findReq.addWhere("ent_no", WhereEnum.LIKE, "%" + req.getEntNo() + "%");
		}

		if (!StringUtils.isBank(req.getStartTime())) {
			findReq.addWhere("create_time", WhereEnum.GE, DateTimeUtil.string2Date(req.getStartTime()));
		}

		if (!StringUtils.isBank(req.getEndTime())) {
			findReq.addWhere("create_time", WhereEnum.LE, DateTimeUtil.string2Date(req.getEndTime()));
		}

		// 数据过滤
		if (BmsUserTypeEnum.sys_user.getKey() == req.getUserType()) {
			// 系统管理员，只能查看系统用户和车场用户
			findReq.addWhere("type", WhereEnum.NE, BmsUserTypeEnum.parking_shop_user.getKey());
		} else if (BmsUserTypeEnum.parking_lot_user.getKey() == req.getUserType()) {
			// 车场管理员，只能查看自己车场的用户和自己车场下的商家用户
			findReq.addWhere("type", WhereEnum.EQ, req.getUserType());
			findReq.addWhere("cust_id", WhereEnum.EQ, req.getCustId());
		} else if (BmsUserTypeEnum.parking_shop_user.getKey() == req.getUserType()) {
			// 商家管理员，只能查看自己的商家用户
			findReq.addWhere("type", WhereEnum.EQ, req.getUserType());
			findReq.addWhere("cust_id", WhereEnum.EQ, req.getShopId());
		} else {
			// TODO 参数错误
		}

		findReq.addOrder("create_time", OrderEnum.DESC);
		findReq.setPage(req.getPageNo(), req.getPageSize());
		Page<BmsUser> userList = page(findReq);
		Page<AllInfoUserVo> resultPage = new Page<>();
		resultPage.setTotalRow(userList.getTotalRow());
		resultPage.setPage(userList.getPage());
		resultPage.setPageSize(userList.getPageSize());
		if (userList.getList() != null && userList.getList().size() > 0) {
			List<BmsUser> bmsUserList = userList.getList();
			List<AllInfoUserVo> userRespVoList = new ArrayList<>();
			for (BmsUser bmsUser : bmsUserList) {
				AllInfoUserVo respVo = getAllInfoUser(bmsUser);
				userRespVoList.add(respVo);
			}
			resultPage.setList(userRespVoList);
		}
		return resultPage;
	}

	@Override
	public AllInfoUserVo getAllInfoUser(Integer userId) throws Exception {
		BmsUser bmsUser = get(userId);
		if (bmsUser != null) {
			return getAllInfoUser(bmsUser);
		}
		return null;
	}

	@Override
	public AllInfoUserVo getAllInfoUser(BmsUser bmsUser) throws Exception {
		AllInfoUserVo allInfoUserVo = new AllInfoUserVo();
		BeanUtils.copyProperties(bmsUser, allInfoUserVo);

		if (BmsUserTypeEnum.sys_user.getKey() == bmsUser.getType()) {
		} else if (BmsUserTypeEnum.parking_lot_user.getKey() == bmsUser.getType()) {
			ParkingLotCustomer parkingLot = parkingLotCustomerDao.get(bmsUser.getCustId());
			if (parkingLot != null) {
				allInfoUserVo.setParkingLotCustomer(parkingLot);
			}
		} else if (BmsUserTypeEnum.parking_shop_user.getKey() == bmsUser.getType()) {
			ParkingShop shop = parkingShopDao.get(bmsUser.getCustId());
			if (shop != null) {
				allInfoUserVo.setParkingShop(shop);
				ParkingLotCustomer parkingLot = parkingLotCustomerDao.get(shop.getParkingLotCustomerId());
				if (parkingLot != null) {
					allInfoUserVo.setParkingLotCustomer(parkingLot);
				}
			}
		}

		FindRequestEntity findUserRoleReq = new FindRequestEntity();
		findUserRoleReq.addWhere("user_id", WhereEnum.EQ, bmsUser.getId());
		List<BmsUserRole> useRoleList = bmsUserRoleDao.find(findUserRoleReq);
		if (useRoleList != null && useRoleList.size() > 0) {
			// 用户角色名 ，只展示第一个
			BmsRole role = bmsRoleDao.get(useRoleList.get(0).getRoleId());
			allInfoUserVo.setBmsRole(role);
		}

		return allInfoUserVo;
	}

	@Override
	public List<BmsUserTypeEnum> listShowUserType(int type) throws Exception {
		List<BmsUserTypeEnum> resultList = new ArrayList<>();
		if (type == BmsUserTypeEnum.sys_user.getKey()) {
			resultList.add(BmsUserTypeEnum.sys_user);
			resultList.add(BmsUserTypeEnum.parking_lot_user);
		} else if (type == BmsUserTypeEnum.parking_lot_user.getKey()) {
			resultList.add(BmsUserTypeEnum.parking_lot_user);
			resultList.add(BmsUserTypeEnum.parking_shop_user);
		} else if (type == BmsUserTypeEnum.parking_shop_user.getKey()) {
			resultList.add(BmsUserTypeEnum.parking_shop_user);
		}
		return resultList;
	}
}
